package cs342.project1.mathNotebook.gui;

import cs342.project1.mathNotebook.data.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import java.io.*;
import java.lang.*;
import java.sql.*;
import java.util.*;

public class DownloadScreen extends JFrame {
	
	private final int width = 700, height = 500;
	private final int X_PADDING = 25;
	private final int Y_PADDING = 50;
	
	private final int TABLE_X = 25;
	private final int TABLE_Y = 25;
	private final int TABLE_WIDTH = width - 2 * TABLE_X;
	private final int TABLE_HEIGHT = 350;	
	
	private JButton downloadButton;
	private JTable table;
	private JScrollPane pane;
	
	private int _userID;
	
	public DownloadScreen(int userID){
		this.setSize(width, height);
        this.setTitle("Download File");
        this.setLocationRelativeTo(null);
        
        _userID = userID;
        
        downloadButton = new JButton("Download");
        downloadButton.setSize(100,30);
        downloadButton.setLocation(width - downloadButton.getWidth() - X_PADDING, height - downloadButton.getHeight() - Y_PADDING);
        this.add(downloadButton);
        
        this.setLayout(null);
        
        this.setResizable(true);
        this.setVisible(true);
        initialize();
	}
	
	public void initialize(){
		// Get data from database
		Object[][] data = new Object[1][1];
	
		data = getData();
		
		// Create the tablemodel
		DownloadTable dTable = new DownloadTable(data);
		// Create the table
		table = new JTable(dTable);
		table.setSize(TABLE_WIDTH, TABLE_HEIGHT);
		table.setLocation(TABLE_X, TABLE_Y);
		table.setVisible(true);
		// Add the table
		this.add(table);
		// Add the table listener
		
		pane = new JScrollPane(table);
		pane.setSize(TABLE_WIDTH,TABLE_HEIGHT);
		pane.setLocation(TABLE_X,TABLE_Y);
		pane.setVisible(true);
		this.add(pane);
		
		this.repaint();
	}
	
	private Object[][] getData() {
		
		try{			
			ArrayList<Integer> permissions = getPermissions(_userID);
			
			MathDatabase mdb = new MathDatabase();
			mdb.open();
			
			mdb.getStatement().executeQuery("SELECT fileID, filename, creatorID, lastModID, isCheckedOut FROM Files");
			ResultSet rs = mdb.getStatement().getResultSet();
			
			int row = 0;
			int col = 1;
			
			int fileID;
			String filename;
			int creator;
			String creator_name;
			int modified;
			String modified_name;
			boolean checkedOut;
			
			rs.first();
			int size = 1;
			while(!rs.isLast()){
				size++;
				rs.next();
			}
			
			Object[][] data = new Object[permissions.size()][4];
			
			rs.first();
			
			while(!rs.isLast()){
				fileID = rs.getInt(col);
				col++;
				if(permissions.contains(fileID)){
					// Get the filename
					filename = rs.getString(col);
					data[row][col-2] = filename;
					col++;
					// Get the creatorID
					creator = rs.getInt(col);
					String userID = getUserID(creator);
					data[row][col-2] = userID;
					col++;
					// Get the lastModID
					modified = rs.getInt(col);
					userID = getUserID(modified);
					data[row][col-2] = userID;
					col++;
					// Get isCheckedOut
					checkedOut = rs.getBoolean(col);
					data[row][col-2] = checkedOut;
					rs.next();
					row++;
					col = 1;
				}
				else{
					rs.next();
					col = 1;
				}
			}
			
			fileID = rs.getInt(col);
			col++;
			if(permissions.contains(fileID)){
				// Get the filename
				filename = rs.getString(col);
				data[row][col-2] = filename;
				col++;
				// Get the creatorID
				creator = rs.getInt(col);
				String userID = getUserID(creator);
				data[row][col-2] = userID;
				col++;
				// Get the lastModID
				modified = rs.getInt(col);
				userID = getUserID(modified);
				data[row][col-2] = userID;
				col++;
				// Get isCheckedOut
				checkedOut = rs.getBoolean(col);
				data[row][col-2] = checkedOut;
				rs.next();
				row++;
				col = 1;
			}
			
			mdb.close();
			return data;
		}
		catch (Exception e){
			System.out.println(e);
			e.printStackTrace();
		}
		
		return null;
		
	}

	private ArrayList<Integer> getPermissions(int id){
		try {
			ArrayList<Integer> permissions = new ArrayList<Integer>();
			
			MathDatabase mdb = new MathDatabase();
			mdb.open();
			
			mdb.getStatement().executeQuery("SELECT fileID, Permission FROM Permissions WHERE userID=" + id);
			ResultSet rs = mdb.getStatement().getResultSet();
			rs.first();
			
			while(!rs.isLast()){
				int type = rs.getInt(2);
				System.out.println(type);
				if (type == 0 || type == 1)
					permissions.add(rs.getInt(1));				
				rs.next();
			}
			
			int type = rs.getInt(2);
			System.out.println(type);
			if (type == 0 || type == 1)
				permissions.add(rs.getInt(1));
			
			mdb.close();
			
			return permissions;
			
		}
		catch (Exception e){
		}
		
		return null;
		
	}
	
	private String getUserID(int id){
		try
		{
		MathDatabase mdb = new MathDatabase();
		mdb.open();
		
		mdb.getStatement().executeQuery("SELECT username FROM Users WHERE userID=" + id);
		ResultSet rs = mdb.getStatement().getResultSet();
		rs.first();
		
		String temp = rs.getString(1);
		mdb.close();
		return temp;
		
		}
		catch(Exception e){}
		return null;
	}
	
	public JButton getDownloadButton(){
		return downloadButton;
	}
	
	public File getSelectedFile(){
		try {
			String filename = (String)table.getValueAt(table.getSelectedRow(),0);
			
			MathDatabase mdb  = new MathDatabase();
			mdb.open();
			mdb.getStatement().executeQuery("SELECT fileContent FROM Files WHERE filename=" + '"'+ filename + '"');
			ResultSet rs = mdb.getStatement().getResultSet();
			
			rs.first();
			
			File              blobFile   = new File(filename);
			FileOutputStream  outStream  = new FileOutputStream(blobFile);
			InputStream       inStream   = rs.getBinaryStream(1);
						      
			int     length  = -1;
			int     size    = inStream.available();
			byte[]  buffer  = new byte[size];
						 
			while ((length = inStream.read(buffer)) != -1)
			{
				outStream.write(buffer, 0, length);
				outStream.flush();
			}
						 
			inStream.close();
			outStream.close();
			mdb.close();
			
			return blobFile;
		}
		catch (Exception e){
			System.out.println(e);
		}
		return null;
	}
	
	public File getPublicKey(){
		try {
			String filename = (String)table.getValueAt(table.getSelectedRow(),0);
			
			MathDatabase mdb  = new MathDatabase();
			mdb.open();
			mdb.getStatement().executeQuery("SELECT lastModID FROM Files WHERE filename=" + '"'+ filename + '"');
			ResultSet rs = mdb.getStatement().getResultSet();
			rs.first();
			
			int lastMod = rs.getInt(1);
			
			MathDatabase mdb2 = new MathDatabase();
			mdb2.open();
			mdb2.getStatement().executeQuery("SELECT priKey FROM Users WHERE userID=" + lastMod);
			ResultSet rs2 = mdb2.getStatement().getResultSet();
			rs2.first();
			
			// blob = rs2.getBlob(1);

			File              blobFile   = new File("pubKey");
			FileOutputStream  outStream  = new FileOutputStream(blobFile);
			InputStream       inStream   = rs2.getBinaryStream(1);
						      
			int     length  = -1;
			int     size    = inStream.available();
			byte[]  buffer  = new byte[size];
						 
			while ((length = inStream.read(buffer)) != -1)
			{
				outStream.write(buffer, 0, length);
				outStream.flush();
			}
						 
			inStream.close();
			outStream.close();
			mdb.close();
			mdb2.close();
		    
			return blobFile;
		}
		catch (Exception e){
			System.out.println(e);
		}
		return null;
	}
	
	public File getDESKey(){
		try {
			String filename = (String)table.getValueAt(table.getSelectedRow(),0);
			
			MathDatabase mdb  = new MathDatabase();
			mdb.open();
			mdb.getStatement().executeQuery("SELECT encryptedDESKey FROM Files WHERE filename=" + '"'+ filename + '"');
			ResultSet rs = mdb.getStatement().getResultSet();
			rs.first();

			File              blobFile   = new File("desKey.dat");
			FileOutputStream  outStream  = new FileOutputStream(blobFile);
			InputStream       inStream   = rs.getBinaryStream(1);
						      
			int     length  = -1;
			int     size    = inStream.available();
			byte[]  buffer  = new byte[size];
						 
			while ((length = inStream.read(buffer)) != -1)
			{
				outStream.write(buffer, 0, length);
				outStream.flush();
			}
						 
			inStream.close();
			outStream.close();
			mdb.close();
		    
			return blobFile;
		}
		catch (Exception e){
			System.out.println(e);
		}
		return null;
	}
	
}